﻿Imports System.Web.Configuration
Imports System.Collections.Generic

Imports NVelocity
Imports NVelocity.App
Imports NVelocity.Context

Partial Class Public_MasterPage
    Inherits My.MyMasterPage

    Protected LoginManager As New BLL_SearchLoginRecord

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim wf As WebForm_ManageImpersonation = TryCast(Context.Handler, WebForm_ManageImpersonation)

        If wf IsNot Nothing Then
            Me.PostLoginProcessing(wf.UserID.Replace("'", "''").ToString())
        End If

        Me.title1.Text += " " + WebConfigurationManager.AppSettings("Version")

        Me.Page.Form.DefaultButton = Me.btnLogin.ID

        If Not IsPostBack Then

            If Request.ServerVariables("HTTP_X_cn") <> "" Then
                Dim userID As String = Request.ServerVariables("HTTP_X_cn").Replace("'", "''").ToString()

                If Me.SSOAutoLogin(userID) = True Then
                    Me.PostLoginProcessing(userID)
                    Return
                End If
            End If

            'Me.Master.SiteMapPath.Provider = SiteMap.Providers("PublicSiteMapProvider")
            Me.SiteMapPath.Provider = SiteMap.Providers("PublicSiteMapProvider")

            Me.FixAjaxBug()
            Me.BindMenu()
            Me.BindSystemContactInfo()
            Me.BindBUContactInfo()
            Me.UpdatePublicAuth()
        End If

        'Dim velocity As New VelocityEngine
        'Dim props As New Commons.Collections.ExtendedProperties

        ''fix bug
        'props.AddProperty("file.resource.loader.path", Server.MapPath("~\App_Data"))
        'velocity.Init(props)

        'Dim template As Template = velocity.GetTemplate("VolunteerCard.txt")

        'Dim context As New VelocityContext
        'context.Put("from", "somewhere")
        'context.Put("to", "someone")
        'context.Put("subject", "Welcome to NVelocity")

        'Dim writer As New IO.StringWriter
        'template.Merge(context, writer)

        'Response.Write(writer.GetStringBuilder().ToString())

    End Sub

    Protected Sub btnLogout_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnLogout.Click
        Response.Redirect(FormsAuthentication.LoginUrl)
    End Sub

    Protected Sub Menu1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles Menu1.ItemDataBound
        If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
            Dim dt As Data.DataTable
            Dim dat As New clsData
            Dim sql As New MyStringBuilder

            sql.AppendFormat("select distinct p.* ")
            sql.AppendFormat("from PublicProgram p ")
            sql.AppendFormat("where p.Parent = '{0}' ", TryCast(e.Item.FindControl("MenuItem"), WebForm_MySlidingMenuGroup).ProgramID)
            sql.AppendFormat("and p.Visible = 'Y' ")
            sql.AppendFormat("order by p.Sequence ")

            dt = dat.GetData(sql.ToString(), Nothing, Data.CommandType.Text, "dt").Tables(0)

            TryCast(e.Item.FindControl("MenuItem"), WebForm_MySlidingMenuGroup).BindGV(dt)
        End If
    End Sub

    Protected Sub btnLogin_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnLogin.Click

        Me.Login()
    End Sub
    '隱藏註冊功能
    'Protected Sub btnRegister_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnRegister.Click
    '    Response.Redirect("~\Public\Register.aspx")
    'End Sub

    Protected Sub btnSSOLogin_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnSSOLogin.Click
        Dim ssoUrl As String = MyObj.GetParameter("Login", "SSOUrl")

        Response.Redirect(ssoUrl)
    End Sub
End Class

Partial Class Public_MasterPage
    Private Sub BindBUContactInfo()
        Dim dat As New clsData
        Dim sql As New MyStringBuilder
        Dim dt As New Data.DataTable

        sql.Length = 0
        sql.AppendFormat("select ParameterValue as BUContactInfo from SystemParameter ")
        sql.AppendFormat("where ParameterType = 'Home' and ParameterName = 'BUContactInfo' ")

        Me.fvBUContactInfo.ChangeMode(FormViewMode.ReadOnly)
        Me.fvBUContactInfo.DataSource = dat.GetData(sql)
        Me.fvBUContactInfo.DataBind()

    End Sub

    Private Sub BindSystemContactInfo()
        Dim dat As New clsData
        Dim sql As New MyStringBuilder
        Dim dt As New Data.DataTable

        sql.Length = 0
        sql.AppendFormat("select ParameterValue as SystemContactInfo from SystemParameter ")
        sql.AppendFormat("where ParameterType = 'Home' and ParameterName = 'SystemContactInfo' ")

        Me.fvSystemContactInfo.ChangeMode(FormViewMode.ReadOnly)
        Me.fvSystemContactInfo.DataSource = dat.GetData(sql)
        Me.fvSystemContactInfo.DataBind()

    End Sub

    Private Sub FixAjaxBug()
        'CalendarExtendar with MultiView + UpdatePanel bug
        'http://dotnetrush.blogspot.com/2008/02/ajax-calendarextender-bug-fixes.html

        Dim url As String = Page.ClientScript.GetWebResourceUrl(GetType(AjaxControlToolkit.ClientCssResourceAttribute), "AjaxControlToolkit.Calendar.Calendar.css")
        Dim myHtmlLink As New HtmlLink()
        myHtmlLink.Href = url
        myHtmlLink.Attributes.Add("rel", "stylesheet")
        myHtmlLink.Attributes.Add("type", "text/css")
        Page.Header.Controls.Add(myHtmlLink)
    End Sub

    Private Sub BindMenu()
        Dim dat As New clsData
        Dim sql As New MyStringBuilder

        sql.AppendFormat("select distinct p.* ")
        sql.AppendFormat("from PublicProgram p ")
        sql.AppendFormat("where p.Parent = 0 ")
        sql.AppendFormat("order by p.Sequence ")

        Me.Menu1.DataSource = dat.GetData(sql.ToString(), Nothing, Data.CommandType.Text, "dt")
        Me.Menu1.DataBind()

        'Response.Write(clsAuth.GetRoleList)
    End Sub

    Private isVolunteer As Boolean

    Private Function SSOAutoLogin(ByVal userID As String) As Boolean
        Dim dat As New clsData
        Dim sql As New MyStringBuilder

        sql.Length = 0
        sql.AppendFormat("select e.* ")
        sql.AppendFormat("from Employee e ")
        sql.AppendFormat("where e.WindowsID = '{0}' or e.EmployeeID = '{0}' ", userID)

        If dat.GetData(sql).Rows.Count > 0 Then
            LoginManager.WriteLoginRecord(userID, True)
            Return True
        Else
            MyObj.ShowMessage("公務帳號尚未建檔")
            LoginManager.WriteLoginRecord(userID, False)
            Return False
        End If
    End Function

    Private Sub Login()
        Dim dat As New clsData
        Dim sql As New MyStringBuilder

        Dim loginResult As Boolean
        Dim requireCheckPassword As Boolean = True
        Dim userID As String = ""

        If MyObj.IsProductionEnvironment() = False Then
            '測試密碼
            If Me.txtPassword.Text = "0000" Then
                requireCheckPassword = False
            End If
        End If

        'If MyObj.IsProductionEnvironment() = True And Me.txtVerificationCode.Text <> Me.VerificationCode1.VerificationCode Then
        '    MyObj.ShowMessage(Me.GetLocalResourceObject("SaveData_InvalidVerificationCode"))
        '    Return
        'End If
        Dim ReplaceUserID As String = ""
        ReplaceUserID = Me.txtUserID.Text.Replace("'", "''").ToString()
        '判斷是否為志工
        sql.Length = 0
        sql.AppendFormat("select v.* ")
        sql.AppendFormat("from VolunteerDistinctView v ")
        sql.AppendFormat("where v.VolunteerID = '{0}' ", ReplaceUserID)

        Dim dt As Data.DataTable

        dt = dat.GetData(sql)
        If dt.Rows.Count > 0 Then
            ' MD5密碼比對
            If requireCheckPassword = False OrElse clsAuth.EncryptPassword(Me.txtPassword.Text) = dt.Rows(0)("Password") Then
                loginResult = True
                Me.isVolunteer = True
                userID = dt.Rows(0)("VolunteerID")

                Response.Cookies("VolunteerStatus").Value = dt.Rows(0)("Active")
                GoTo Login_Success
            Else
                MyObj.ShowMessage("密碼輸入錯誤")
                LoginManager.WriteLoginRecord(dt.Rows(0)("VolunteerID"), False)
                Return
            End If
        End If

        '判斷是否為民間團體
        sql.Length = 0
        sql.AppendFormat("select p.* ")
        sql.AppendFormat("from Person p ")
        sql.AppendFormat("where p.PersonID = '{0}' ", ReplaceUserID)

        dt = dat.GetData(sql)

        If dt.Rows.Count > 0 Then
            ' MD5密碼比對
            If requireCheckPassword = False OrElse clsAuth.EncryptPassword(Me.txtPassword.Text) = dt.Rows(0)("Password") Then
                loginResult = True
                userID = dt.Rows(0)("PersonID")

                GoTo Login_Success
            Else
                MyObj.ShowMessage("密碼輸入錯誤")
                LoginManager.WriteLoginRecord(dt.Rows(0)("PersonID"), False)
                Return
            End If
        End If

        sql.Length = 0
        sql.AppendFormat("select e.* ")
        sql.AppendFormat("from Employee e ")
        sql.AppendFormat("where  e.EmployeeID = '{0}' ", ReplaceUserID)

        dt = dat.GetData(sql)
        '判斷是否為機關人員
        If dt.Rows.Count > 0 Then

            '非公務帳號
            If TypeOf dt.Rows(0)("WindowsID") Is DBNull Or dt.Rows(0)("WindowsID").ToString() = "" Then
                If TypeOf dt.Rows(0)("Password") Is DBNull Then
                    dt.Rows(0)("Password") = clsAuth.EncryptPassword("")
                End If

                ' MD5密碼比對
                If requireCheckPassword = False OrElse clsAuth.EncryptPassword(Me.txtPassword.Text) = dt.Rows(0)("Password") Then
                    loginResult = True
                    userID = dt.Rows(0)("EmployeeID")

                    GoTo Login_Success
                Else
                    MyObj.ShowMessage("密碼輸入錯誤")
                    LoginManager.WriteLoginRecord(dt.Rows(0)("EmployeeID"), False)
                    Return
                End If
            ElseIf requireCheckPassword = False Then
                loginResult = True
                userID = dt.Rows(0)("EmployeeID")
                GoTo Login_Success
            Else
                '公務帳號要從 SSO 登入

                Response.Redirect(clsAuth.GetSSOUrl())

                'ElseIf requireCheckPassword = False OrElse dat.CheckNTAccount(Me.txtUserID.Text, Me.txtPassword.Text, Me.Domain) = True Then
                '    loginResult = True
                '    userID = dt.Rows(0)("EmployeeID")
                '    GoTo Login_Success
                'Else
                '    MyObj.ShowMessage("密碼輸入錯誤")
                '    Return


            End If
        Else
            MyObj.ShowMessage("您的公務帳號尚未建檔,請聯絡志工系統管理人員")
            Return
        End If

Login_Success:
        If loginResult = True Then
            LoginManager.WriteLoginRecord(userID, True)
            Me.PostLoginProcessing(userID)
        Else
            MyObj.ShowMessage("查無此帳號")
            LoginManager.WriteLoginRecord(txtUserID.Text, False)
        End If
    End Sub

    ''' <summary>
    ''' 登入成功後之處理
    ''' </summary>
    ''' <param name="userID"></param>
    ''' <remarks></remarks>
    Private Sub PostLoginProcessing(ByVal userID As String)
        Me.BindData(userID)

        FormsAuthentication.SetAuthCookie(userID, False)

        '依據此組織資料，判斷表單裡每筆資料之權限
        '登出後清空此資料以節省空間

        '單位權限已停用
        clsAuth.BuildOrganizationAuth(userID)

        '依據此表單權限資料，判斷登入者對表單之權限
        '登出後清空此資料以節省空間
        clsAuth.BuildProgramAuth(userID)

        'MyObj.ShowMessage(clsAuth.GetUser().UserType.Value)
        'MyObj.ShowMessage(clsAuth.GetUser().UserType = My.UserType.Volunteer)
        'Return
        If FormsAuthentication.GetRedirectUrl(userID, False) <> "" Then
            '登入預設首頁,避免ID切換但無原頁面權限
            Response.Redirect(clsAuth.GetDefaultUrl())
            'FormsAuthentication.RedirectFromLoginPage(userID, False)
        Else
            Response.Redirect(clsAuth.GetDefaultUrl())
        End If
    End Sub

    Private ReadOnly Property UserType() As My.UserType
        Get
            Return New My.UserType(Response.Cookies("UserTypeValue").Value)
        End Get
    End Property

    Private ReadOnly Property IsVolunteerLeader() As Boolean
        Get
            If Response.Cookies("VolunteerLeader").Value = "Y" Then
                Return True
            Else
                Return False
            End If
        End Get
    End Property

    Private Sub BindData(ByVal userID As String)
        Request.Cookies.Clear()
        Response.Cookies.Clear()

        Dim dt As Data.DataTable
        Dim dat As New clsData
        Dim sql As New MyStringBuilder
        Dim customRoleList As New List(Of String)

        '取得個人資訊
        sql.Length = 0
        sql.AppendFormat("select u.UserName,u.UserType,u.RegionID,u.RegionType,u.Active ")
        sql.AppendFormat("from [User] u ")
        sql.AppendFormat("where u.UserID = '{0}' ", userID)

        dt = dat.GetData(sql)
        MyObj.WriteLog(Me.txtUserID.Text & "," & Now.ToString() & "," & MyObj.getIP() & "," & sql.ToString())

        Response.Cookies("UserName").Value = HttpUtility.UrlEncode(dt.Rows(0)("UserName").ToString())
        Response.Cookies("UserName").Expires = Now.AddMonths(1)

        Response.Cookies("UserTypeValue").Value = dt.Rows(0)("UserType")
        Response.Cookies("UserTypeValue").Expires = Now.AddMonths(1)

        Response.Cookies("VolunteerLeader").Value = "N"

        If Me.UserType = My.UserType.Volunteer Then
            Response.Cookies("UserType").Value = HttpUtility.UrlEncode("環保志工")

            '判斷是否有擔任志工隊職務
            sql.Length = 0
            sql.AppendFormat("select oom.Source, RoleName = cm_Source.Text,vor.VorganizationName from OtherOrganizationMapping oom ")
            sql.AppendFormat("inner join VOrganizationMapping vom on oom.UserID = vom.VolunteerID and oom.UOrganizationID = dbo.GetUOrganizationID(-1,vom.VOrganizationID) ")
            sql.AppendFormat("inner join VOrganization vor on oom.UOrganizationID=dbo.GetUOrganizationID(-1,vor.VOrganizationID) ")
            sql.AppendFormat("inner join CodeMapping cm_Source on oom.Source = cm_Source.Value and cm_Source.TableName = 'OtherOrganizationMapping' and cm_Source.ColumnName = 'Source' ")
            sql.AppendFormat("where oom.AuthName = 'Admin' ")
            sql.AppendFormat("and UserID = '{0}' ", userID)

            Dim dtVolunteerRoles As Data.DataTable = dat.GetData(sql)

            If dtVolunteerRoles.Rows.Count > 0 Then
                Response.Cookies("UserType").Value = HttpUtility.UrlEncode(dtVolunteerRoles.Rows(0)("RoleName"))
                Response.Cookies("OrganizationName").Value = HttpUtility.UrlEncode(dtVolunteerRoles.Rows(0)("VOrganizationName"))

                customRoleList.Add(dtVolunteerRoles.Rows(0)("Source"))

                Response.Cookies("VolunteerLeader").Value = "Y"
                ' Response.Cookies("VolunteerLeader").Expires = Now.AddMonths(1)
            End If

            'Response.Cookies("UserType").Value = ""

            'For Each dr As Data.DataRow In dat.GetData(sql).Rows
            '    Response.Cookies("UserType").Value = HttpUtility.UrlEncode(dr("RoleName"))

            '    '皆適用志工隊長權限
            '    Response.Cookies("VolunteerLeader").Value = "Y"
            '    Response.Cookies("VolunteerLeader").Expires = Now.AddMonths(1)
            'Next

            '依志工狀態設定身份類別
            sql.Length = 0
            sql.AppendFormat("select top 1 v.Active, vo.VOrganizationName from VolunteerDistinctView v ")
            sql.AppendFormat("left join VolunteerView vv on v.VolunteerID = vv.VolunteerID ")
            sql.AppendFormat("left join VOrganization vo on vv.VOrganizationID = vo.VOrganizationID ")
            sql.AppendFormat("where 1=1 ")
            ' sql.AppendFormat("and vv.VOrganizationID <> 0 ")
            sql.AppendFormat("and v.VolunteerID = '{0}' ", userID)
            sql.AppendFormat("order by vo.VOrganizationName desc ")
            Dim dtVolunteer As Data.DataTable = dat.GetData(sql)

            If dtVolunteer.Rows(0)("Active") <> My.VolunteerStatus.VBooked Then
                Response.Cookies("UserType").Value = HttpUtility.UrlEncode("志工儲備人員")
            End If

            If dtVolunteer.Rows(0)("VOrganizationName") IsNot DBNull.Value AndAlso dtVolunteerRoles.Rows.Count = 0 Then
                Response.Cookies("OrganizationName").Value = HttpUtility.UrlEncode(dtVolunteer.Rows(0)("VOrganizationName"))
            ElseIf dtVolunteer.Rows(0)("VOrganizationName") Is DBNull.Value AndAlso dtVolunteerRoles.Rows.Count = 0 Then
                Response.Cookies("OrganizationName").Value = HttpUtility.UrlEncode("未加入志工隊")
            End If

            '志工可能有棣屬多個志工隊
            Response.Cookies("UOrganizationID").Value = ""
        Else
            Dim dtInternalUser As Data.DataTable

            '若屬於運用單位人員, 傳回單位資訊
            sql.Length = 0
            sql.AppendFormat("select u.UOrganizationID,u.OrganizationName ")
            sql.AppendFormat(",o.OrganizationName ")
            sql.AppendFormat("from [InternalUser] u ")
            sql.AppendFormat("inner join OrganizationView o on u.UOrganizationID = o.UOrganizationID ")
            sql.AppendFormat("where u.UserID = '{0}' ", userID)

            dtInternalUser = dat.GetData(sql)

            Response.Cookies("UOrganizationID").Value = dtInternalUser.Rows(0)("UOrganizationID")
            '  Response.Cookies("UOrganizationID").Expires = Now.AddMonths(1)

            Response.Cookies("OrganizationName").Value = HttpUtility.UrlEncode(dtInternalUser.Rows(0)("OrganizationName"))
            ' Response.Cookies("OrganizationName").Expires = Now.AddMonths(1)

            If Me.UserType = My.UserType.Employee Then
                Response.Cookies("UserType").Value = HttpUtility.UrlEncode("公務帳號")
            ElseIf Me.UserType = My.UserType.Person Then
                Response.Cookies("UserType").Value = HttpUtility.UrlEncode("民間團體")
            End If

        End If

        Response.Cookies("VolunteerStatus").Value = dt.Rows(0)("Active")
        'Response.Cookies("VolunteerStatus").Expires = Now.AddMonths(1)

        Response.Cookies("RegionID").Value = dt.Rows(0)("RegionID")
        ' Response.Cookies("RegionID").Expires = Now.AddMonths(1)

        Response.Cookies("RegionType").Value = dt.Rows(0)("RegionType")
        'Response.Cookies("RegionType").Expires = Now.AddMonths(1)

        '取得職務列表
        sql.Length = 0
        sql.AppendFormat("select ru.RoleID ")
        sql.AppendFormat("from RoleUserMappingView ru ")
        sql.AppendFormat("where ru.UserID = '{0}' ", userID)

        dt = dat.GetData(sql.ToString(), Nothing, Data.CommandType.Text, "dt").Tables(0)

        Dim roleList As New List(Of String)

        For Each dr As Data.DataRow In dt.Rows
            roleList.Add(dr("RoleID"))
        Next

        If roleList.Count = 0 Then
            'roleList.Add("0")
        End If

        'If Me.isVolunteer = True Then
        If Me.UserType = My.UserType.Volunteer Then
            roleList.Add(clsAuth.GetRoleIDByName("Volunteer"))
        Else
            roleList.Add(clsAuth.GetRoleIDByName("Employee"))
        End If

        'If Me.IsVolunteerLeader = True Then
        '    roleList.Add(clsAuth.GetRoleIDByName("VolunteerLeader"))
        'End If

        For Each role As String In customRoleList
            roleList.Add(clsAuth.GetRoleIDByName(role))
        Next

        roleList.Add(clsAuth.GetRoleIDByName("Everyone"))

        Response.Cookies("RoleList").Value = String.Join(",", roleList.ToArray())
        '  Response.Cookies("RoleList").Expires = Now.AddMonths(1)

        Using scope As New Transactions.TransactionScope
            sql.Length = 0
            sql.AppendFormat("delete UserRoleAuth ")
            sql.AppendFormat("where UserID = '{0}' ", userID)
            dat.AccData(sql)

            For Each roleID As String In roleList
                sql.Length = 0
                sql.AppendFormat("insert UserRoleAuth (UserID, RoleID) ")
                sql.AppendFormat("select '{0}' ", userID)
                sql.AppendFormat(", '{0}' ", roleID)

                dat.AccData(sql)
            Next
            scope.Complete()
        End Using

        'If roleList.Contains(clsAuth.GetRoleIDByName("VolunteerLeader")) Then
        '    Response.Cookies("UserType").Value = HttpUtility.UrlEncode("志工隊長")

        '    Response.Cookies("VolunteerLeader").Value = "Y"
        '    Response.Cookies("VolunteerLeader").Expires = Now.AddMonths(1)
        'End If

        ' Response.Cookies("UserType").Expires = Now.AddMonths(1)

    End Sub

    Private Sub UpdatePublicAuth()
        Dim userID As String = ""
        Dim dat As New clsData
        Dim sql As New MyStringBuilder
        Dim roleList As New List(Of String)

        roleList.Add(clsAuth.GetRoleIDByName("Everyone"))

        Using scope As New Transactions.TransactionScope
            sql.Length = 0
            sql.AppendFormat("delete UserRoleAuth ")
            sql.AppendFormat("where UserID = '{0}' ", userID)
            dat.AccData(sql)

            For Each roleID As String In roleList
                sql.Length = 0
                sql.AppendFormat("insert UserRoleAuth (UserID, RoleID) ")
                sql.AppendFormat("select '{0}' ", userID)
                sql.AppendFormat(", '{0}' ", roleID)

                dat.AccData(sql)
            Next
            scope.Complete()
        End Using
    End Sub

    Private ReadOnly Property Domain()
        Get
            Return WebConfigurationManager.AppSettings("NTDomain")
        End Get
    End Property

    Public Overrides ReadOnly Property SiteMapPath() As System.Web.UI.WebControls.SiteMapPath
        Get
            Return Me.SiteMapPath1
        End Get
    End Property
End Class